package org.simple.web.jwt.filter;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 项目名称：web-security-jwt
 * 类名称：UserLoginFilter
 * 类描述：UserLoginFilter
 * 创建时间：2018/9/12
 *
 * @author guihuo   (E-mail:1620657419@qq.com)
 * @version v1.0
 */
public class UserLoginFilter extends AbstractAuthenticationProcessingFilter {

    private static final String DEFAULT_USERNAME_PARAMETER = "username";

    private static final String DEFAULT_PASSWORD_PARAMETER = "password";


    public UserLoginFilter(AuthenticationManager authenticationManager, String tokenUrl) {
        super(new AntPathRequestMatcher(tokenUrl));
        setAuthenticationManager(authenticationManager);
    }


    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
//        if (!request.getMethod().equals("POST")) {
//            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
//        }

    	
    	String name = null,pwd = null;
    	String contentType = request.getContentType();
    	if(contentType.contains("application/json")) {
    		String requestJson = getRequestJson(request);
    		Map convertValue = new ObjectMapper().readValue(requestJson, HashMap.class);
    		
    		name = (String) convertValue.get(DEFAULT_USERNAME_PARAMETER);
    		pwd = (String) convertValue.get(DEFAULT_PASSWORD_PARAMETER);
    	}else {
			name = obtainUsername(request);
			pwd = obtainPassword(request);
		}
    	
        return this.getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(
        		name, pwd
        ));
    }

    private String obtainUsername(HttpServletRequest request) {
    	Map<String, String[]> parameterMap = request.getParameterMap();
        String username = request.getParameter(DEFAULT_USERNAME_PARAMETER);
        if (username == null) {
            username = "";
        }
        return username.trim();
    }

    private String obtainPassword(HttpServletRequest request) {
        String password = request.getParameter(DEFAULT_PASSWORD_PARAMETER);
        if (password == null) {
            password = "";
        }
        return password;
    }
    
    
    public  String getRequestJson(HttpServletRequest request) {
        boolean isGetRequest = request.getMethod().toLowerCase().equals("get");
        try {
            if (isGetRequest) {
                return new String(request.getQueryString().getBytes(
                        "ISO-8859-1"), "UTF-8").replaceAll("%22", "\"");
            }
            int contentLength = request.getContentLength();
            if (contentLength < 0) {
                return null;
            }
            byte buffer[] = new byte[contentLength];
            for (int i = 0; i < contentLength;) {

                int readlen = request.getInputStream().read(buffer, i,
                        contentLength - i);
                if (readlen == -1) {
                    break;
                }
                i += readlen;
            }
            return new String(buffer, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
